package com.secondriver.url.filter.match.groovy

import java.util.List;
import java.util.regex.Pattern

import com.secondriver.url.filter.match.URLCacheObject;
import com.secondriver.url.filter.match.URLPatternMatch;
import com.secondriver.url.filter.urlrealm.Subject;
import static com.secondriver.url.filter.match.groovy.DefalutURLPatternMatch.*;

/**
 *  
 *  Ant风格的模式匹配
 *  
 *  下面是Ant风格的说明：
 *  
 *    ? matches one character
 *    * matches zero or more characters
 *	  ** matches zero or more 'directories' in a path
 *
 *	com/t?st.jsp - matches com/test.jsp but also com/tast.jsp or com/txst.jsp
 *
 *	com/*.jsp - matches all .jsp files in the com directory
 *
 *  com/"**"(&#42;&#42;)/test.jsp - matches all test.jsp files underneath the com path
 *
 *  org/springframework/"**"/*.jsp - matches all .jsp files underneath the org/springframework path
 *
 *  org/"**"/servlet/bla.jsp - matches org/springframework/servlet/bla.jsp but also org/springframework/testing/servlet/bla.jsp and org/servlet/bla.jsp
 *
 *  这里只做了是否匹配判断，未做符合规则的匹配精确处理
 */
class AntURLPatternMatch implements URLPatternMatch{

	@Override
	public boolean isPass(String requestURI, Set<String> urls) {
		urls=urls.collect{
			it=fixedUrlPrefix(it);
		}
		requestURI=fixedUrlPrefix(requestURI);

		def nopatterns=urls.findAll({ it->
			return !isPattern(it);
		});

		if(nopatterns.size() > 0 && urls.any { it->
			return requestURI.equals(it);
		}){
			return true;
		}else{
			def antPatterns=urls.findAll({ it->
				return isPattern(it);
			});
			return	antPatterns.any { it->
				return antPatternMatch(it, requestURI);
			}
		}
	}

	private def isPattern={ pattern->
		return pattern.contains('*') || pattern.contains('?') ;
	}

	private boolean antPatternMatch(String pattern, String requestURI){
		def patterns=splitUrlToParts(pattern);
		StringBuilder sb=new StringBuilder();
		patterns.each { it->
			if('**' == it){
				sb.append("(/${CHARACTER}*)*");
			}else{
				sb.append('/').append(it.replace('?',"${CHARACTER}?").replace('*', "${CHARACTER}*"));
			}
		}
		Pattern p=Pattern.compile(sb.toString());
		return p.matcher(requestURI).matches();
	}
}